using SharpAdbClient;
using System;
using System.Collections.Concurrent;  // 线程安全集合（参考网页4）
using System.IO;                     // 文件操作核心命名空间（参考网页7）
using System.Linq;
using System.Threading;
using System.Threading.Tasks;        // 异步任务支持（参考网页17）

/// <summary>
/// 高级Logcat接收器，实现线程安全的日志缓冲和动态写入优化
/// （集成设备状态监控和异常处理机制）
/// </summary>
public class AdvancedLogcatReceiver : IShellOutputReceiver, IDisposable
{
    private const int MaxBufferSize = 1024 * 1024;  // 最大缓冲1MB防止内存溢出（参考网页4）
    private const int InitialFlushInterval = 1000;  // 初始写入间隔1秒
    private readonly string _logPath;               // 日志文件路径
    private readonly ConcurrentQueue<string> _logQueue = new();  // 线程安全队列（参考网页4）
    private int _currentBufferSize;                  // 当前缓冲字节数
    private readonly CancellationTokenSource _cts;   // 取消令牌（参考网页14）
    private readonly StreamWriter _writer;           // 文件写入流（参考网页7）
    private readonly DeviceData _targetDevice;        // 目标设备信息
    private int _flushInterval = InitialFlushInterval; // 动态写入间隔
    private bool _disposed;                          // 资源释放标记

    public bool ParsesErrors => false;  // 禁用错误解析

    public AdvancedLogcatReceiver(
        string logPath,
        DeviceData device,
        CancellationTokenSource cts,
        string logcatArguments = "-v time")
    {
        _logPath = logPath;
        _targetDevice = device;
        _cts = cts;
        // 创建追加写入的文件流，禁用自动刷新提升性能（参考网页7）
        _writer = new StreamWriter(logPath, append: true) { AutoFlush = false };  
        // 启动动态间隔调整任务
        Task.Run(AdjustFlushIntervalAsync);  
        // 启动日志写入主任务
        Task.Run(WriteLogsAsync);  
    }

    /// <summary>
    /// 添加日志行到缓冲队列（线程安全操作）
    /// </summary>
    public void AddOutput(string line)
    {
        if (_cts.IsCancellationRequested)
            return;

        // 添加时间戳并加入队列（参考网页5）
        _logQueue.Enqueue($"{DateTime.Now:HH:mm:ss.fff} | {line}");  
        // 原子操作更新缓冲大小（含换行符2字节）
        Interlocked.Add(ref _currentBufferSize, line.Length + 2);  

        // 动态调整写入频率：当缓冲超过80%容量时缩短间隔（参考网页5优化策略）
        if (_currentBufferSize > MaxBufferSize * 0.8)
            Interlocked.Exchange(ref _flushInterval, Math.Max(100, _flushInterval / 2));
    }

    /// <summary>
    /// 强制刷新缓冲区到文件
    /// </summary>
    public void Flush() => WriteBatch();

    /// <summary>
    /// 实现IDisposable接口，确保资源释放（参考网页9）
    /// </summary>
    public void Dispose()
    {
        if (_disposed) return;
        _disposed = true;
        _writer.Dispose();       // 关闭文件流
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// 日志写入任务（核心循环）
    /// </summary>
    private async Task WriteLogsAsync()
    {
        while (!_cts.IsCancellationRequested)
        {
            // 按当前间隔等待，支持取消令牌（参考网页14）
            await Task.Delay(_flushInterval, _cts.Token).ConfigureAwait(false);  
            WriteBatch();
        }
        WriteBatch(); // 最终强制写入
    }

    /// <summary>
    /// 动态调整写入间隔的后台任务（5秒恢复初始间隔）
    /// </summary>
    private async Task AdjustFlushIntervalAsync()
    {
        while (!_cts.IsCancellationRequested)
        {
            await Task.Delay(5000).ConfigureAwait(false);
            Interlocked.Exchange(ref _flushInterval, InitialFlushInterval);
        }
    }

    /// <summary>
    /// 批量写入文件的核心方法
    /// </summary>
    private void WriteBatch()
    {
        try
        {
            int count = 0;
            // 批量出队写入（减少IO操作次数）
            while (_logQueue.TryDequeue(out var line))  
            {
                _writer.WriteLine(line);
                count++;
            }
            _writer.Flush();  // 手动刷新缓冲区到磁盘（参考网页7）
            Interlocked.Exchange(ref _currentBufferSize, 0);  // 重置缓冲计数器
            
            if (count > 0)
                Console.WriteLine($"已写入 {count} 条日志，当前间隔: {_flushInterval}ms");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"日志写入失败: {ex.Message}");
            _cts.Cancel();  // 严重错误时终止整个任务链（参考网页14）
        }
    }
}

/// <summary>
/// 优化的日志监控器（实现设备热插拔检测和资源管理）
/// </summary>
public class OptimizedLogMonitor : IDisposable
{
    private readonly AdbClient _adb = new();           // ADB客户端实例
    private readonly DeviceMonitor _deviceMonitor;     // 设备监控器
    private CancellationTokenSource _logcatCts;        // 日志任务取消令牌
    private AdvancedLogcatReceiver _receiver;         // 日志接收器实例
    private Task _logcatTask;                          // 日志采集任务
    private bool _disposed;                            // 资源释放标记

    public OptimizedLogMonitor()
    {
        // 初始化设备监控器（参考网页1的ADB最佳实践）
        _deviceMonitor = new DeviceMonitor(new AdbSocket());  
        _deviceMonitor.DeviceConnected += OnDeviceConnected;
        _deviceMonitor.DeviceDisconnected += OnDeviceDisconnected;
    }

    /// <summary>
    /// 启动监控主循环
    /// </summary>
    public async Task StartAsync(string logPath = "logcat.log")
    {
        await RestartAdbServerAsync();  // 重启ADB确保稳定性（参考网页1）
        _deviceMonitor.Start();

        var initialDevices = _adb.GetDevices();
        if (initialDevices.Any())
            await StartLogcatAsync(initialDevices.First(), logPath);

        await Task.Delay(Timeout.Infinite).ConfigureAwait(false);  // 保持主线程活动
    }

    /// <summary>
    /// 启动日志采集任务（支持设备重连时重启）
    /// </summary>
    private async Task StartLogcatAsync(DeviceData device, string logPath)
    {
        _logcatCts?.Dispose();
        _logcatCts = new CancellationTokenSource();
        // 创建接收器实例（每个设备独立日志文件）
        _receiver = new AdvancedLogcatReceiver($"logcat_{device.Serial}.log", device, _logcatCts);

        try
        {
            // 异步执行logcat命令（参考网页1的ADB调用）
            _logcatTask = _adb.ExecuteRemoteCommandAsync(
                "logcat -v time *:V",  // 自定义日志格式和级别
                device,
                _receiver,
                _logcatCts.Token
            );

            await _logcatTask.ConfigureAwait(false);  // 异步等待任务完成
        }
        catch (TaskCanceledException)
        {
            Console.WriteLine("日志采集已取消");
        }
        catch (AdbException ex) when (ex.Message.Contains("device not found"))
        {
            Console.WriteLine($"设备已断开: {device.Serial}");  // 设备异常处理（参考用户需求3）
        }
        catch (Exception ex)
        {
            Console.WriteLine($"严重错误: {ex}");
            StopLogcat();
        }
    }

    /// <summary>
    /// 安全停止日志采集（参考网页14的取消机制）
    /// </summary>
    private void StopLogcat()
    {
        _logcatCts?.Cancel();
        _receiver?.Dispose();
        _logcatTask?.Wait(1000);  // 最多等待1秒完成（参考网页14的Join策略）
    }

    /// <summary>
    /// 重启ADB服务确保连接稳定性（参考网页1的ADB最佳实践）
    /// </summary>
    private async Task RestartAdbServerAsync()
    {
        try
        {
            await _adb.RestartServerAsync().ConfigureAwait(false);
            Console.WriteLine("ADB服务已重启");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"ADB启动失败: {ex.Message}");
            throw;
        }
    }

    // 设备连接事件处理（自动启动日志采集）
    private async void OnDeviceConnected(object sender, DeviceDataEventArgs e)
    {
        Console.WriteLine($"设备已连接: {e.Device.Serial}");
        await StartLogcatAsync(e.Device, $"logcat_{e.Device.Serial}.log");
    }

    // 设备断开事件处理（安全停止日志）
    private void OnDeviceDisconnected(object sender, DeviceDataEventArgs e)
    {
        Console.WriteLine($"设备断开: {e.Device.Serial}");
        StopLogcat();  // 实现用户需求3的设备中断处理
    }

    /// <summary>
    /// 实现资源释放模式（参考网页9的IDisposable最佳实践）
    /// </summary>
    public void Dispose()
    {
        if (_disposed) return;
        _disposed = true;
        StopLogcat();
        _deviceMonitor.Dispose();
        _adb.Dispose();
    }
}

// 使用示例（演示正确资源管理）
class Program
{
    static async Task Main()
    {
        using var monitor = new OptimizedLogMonitor();  // 自动释放资源
        await monitor.StartAsync();
    }
}